#define __KEY_C__

#include "../Config.h"

KEYBOARD::KEYBOARD()
{
  key_accepted=1; key_pressed=0;
  last_key=0xFF; key=0xFF;
  strobe=0;
  *((volatile char *)0x40000004)=0x0000000F;
};

void KEYBOARD::Scan(void)
{
  unsigned int answer;
  switch(keyboard.strobe)
  {
    case 0:
      keyboard.rv=0xFF;
      answer= AT91C_BASE_SYS->PIOB_PDSR&0x00000038; answer+=AT91C_BASE_SYS->PIOA_PDSR&0x20000000; //Read Out 1 strobe
      switch(answer)
      {
        case 0x00000038 :  keyboard.rv = KEY_DOWN; break;		// Down   in1
        case 0x20000030 :  keyboard.rv = KEY_0; break;			// 0      in2
        case 0x20000028 :  keyboard.rv = KEY_MENU; break;		// Menu   in3
        case 0x20000018 :  keyboard.rv = KEY_ENTER; break;		// ENTER  in4
      }
      keyboard.strobe++;
      *((volatile char *)0x40000004)=0x0000000D; //Set Out 2
      break;
    case 1:
      answer= AT91C_BASE_SYS->PIOB_PDSR&0x00000038; answer+=AT91C_BASE_SYS->PIOA_PDSR&0x20000000; //Read Out 2 strobe
      switch(answer)
      {
        case 0x00000038 : keyboard.rv = KEY_UP; break; 		// Up     in1
        case 0x20000030 : keyboard.rv = KEY_7; break;          	// 7      in2
        case 0x20000028 : keyboard.rv = KEY_8; break;          	// 8      in3
        case 0x20000018 : keyboard.rv = KEY_9; break;	        // 9      in4
      }
      keyboard.strobe++;
      *((volatile char *)0x40000004)=0x0000000B; //Set Out 3
      break;
    case 2:
      answer= AT91C_BASE_SYS->PIOB_PDSR&0x00000038; answer+=AT91C_BASE_SYS->PIOA_PDSR&0x20000000; //Read Out 3 strobe
      switch(answer)
      {
        case 0x00000038 : keyboard.rv = KEY_RIGHT; break; 	// Right  in1
        case 0x20000030 : keyboard.rv = KEY_4; break;          	// 4      in2
        case 0x20000028 : keyboard.rv = KEY_5; break;          	// 5      in3
        case 0x20000018 : keyboard.rv = KEY_6; break;	        // 6      in4
      }
      keyboard.strobe++;
      *((volatile char *)0x40000004)=0x00000007; //Set Out 4
      break;
    case 3:
      answer= AT91C_BASE_SYS->PIOB_PDSR&0x00000038; answer+=AT91C_BASE_SYS->PIOA_PDSR&0x20000000; //Read Out 4 strobe
      switch(answer)
      {
        case 0x00000038 : keyboard.rv = KEY_LEFT; break; 	// Left   in1
        case 0x20000030 : keyboard.rv = KEY_1; break;          	// 1      in2
        case 0x20000028 : keyboard.rv = KEY_2; break;          	// 2      in3
        case 0x20000018 : keyboard.rv = KEY_3; break;	        // 3      in4
      }
      keyboard.strobe=0;
      *((volatile char *)0x40000004)=0x0000000E; //Set Out 1
      if(keyboard.key_accepted) // && ((menu.main_mode == TOP) || (menu.main_mode == MENU)))
      {
        keyboard.key=keyboard.rv;
        if((keyboard.key != keyboard.last_key) || ((!keyboard.key_delay_counter)&&(!keyboard.key_retry_counter)))
        {
          keyboard.last_key = 0xFF;
          if(keyboard.key != 0xFF)
          {
            keyboard.last_key = keyboard.key; keyboard.key_retry_counter = KB_RETRY; keyboard.key_pressed=1; keyboard.key_accepted = 0;
          }
          else
            keyboard.key_delay_counter = KB_DELAY;
        }
        else
        if((keyboard.key == KEY_DOWN)||(keyboard.key == KEY_UP)||(keyboard.key == KEY_RIGHT)||(keyboard.key == KEY_LEFT))
        {
          if(keyboard.key_delay_counter) keyboard.key_delay_counter--;
          if(keyboard.key_retry_counter) keyboard.key_retry_counter--;
        }
      }
      break;
  }
};


bool KEYBOARD::Keypressed(void)
{
  return key_pressed; //(key==0xFF)?false:true;
};

unsigned int KEYBOARD::Read_Key(void)
{
  unsigned int ret=key;
  key_accepted=1; key_pressed=0;
  return ret;
};
